package gitlet;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;// 这个导入是正确的

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.*;

import static gitlet.CommitTest.deleteDirectory;
import static gitlet.Repository.GITLET_DIR;
import static gitlet.Repository.GITLET_DIR_OBJECT;
import static gitlet.Repository.GITLET_DIR_OBJECT_BLOBS;
import static gitlet.Utils.join;
import static gitlet.Utils.sha1;
import static org.junit.Assert.*;

public class MergeUtilTest {

    @Before
    public void setup() {
        if (Repository.GITLET_DIR.exists()) {
            deleteDirectory(Repository.GITLET_DIR);
        }
        ;
        GITLET_DIR.mkdir();
        GITLET_DIR_OBJECT.mkdir();
        GITLET_DIR_OBJECT_BLOBS.mkdir();
    }

    @Test
    public void findAllCommitAncestorsTest() {
        // 创建提交 init
        Commit init = new Commit("Initial commit", null, null, "2024-01-01 10:00", new HashMap<>(), new ArrayList<>());
        init.saveCommit();
        // 创建提交 A
        HashMap<String, String> filesToAddA = new HashMap<>();
        filesToAddA.put("fileA.txt", "content A");
        Commit commitA = new Commit("Commit A", init.getCommitID(), null, "2024-01-02 10:00", filesToAddA, new ArrayList<>());
        commitA.saveCommit();
        // 创建提交 D 和 C
        Commit commitD = new Commit("Commit D", commitA.getCommitID(), null, "2024-01-03 10:00", new HashMap<>(), new ArrayList<>());
        Commit commitC = new Commit("Commit C", commitA.getCommitID(), null, "2024-01-03 11:00", new HashMap<>(), new ArrayList<>());
        commitC.saveCommit();
        commitD.saveCommit();
        // 创建提交 E 和 F
        HashMap<String, String> filesToAddE = new HashMap<>();
        filesToAddE.put("fileE.txt", "content E");
        Commit commitE = new Commit("Commit E", commitC.getCommitID(), null, "2024-01-04 10:00", filesToAddE, new ArrayList<>());
        commitE.saveCommit();
        HashMap<String, String> filesToAddF = new HashMap<>();
        filesToAddF.put("fileF.txt", "content F");
        Commit commitF = new Commit("Commit F", commitE.getCommitID(), null, "2024-01-05 10:00", filesToAddF, new ArrayList<>());
        commitF.saveCommit();
        // 创建提交 G，G 是 E 和 F 的合并结果
        Commit commitG = new Commit("Commit G", commitE.getCommitID(), commitF.getCommitID(), "2024-01-06 10:00", new HashMap<>(), new ArrayList<>());
        commitG.saveCommit();
        // 创建提交 lol, how, far
        Commit commitLol = new Commit("Commit lol", commitG.getCommitID(), null, "2024-01-07 10:00", new HashMap<>(), new ArrayList<>());
        commitLol.saveCommit();
        Commit commitHow = new Commit("Commit how", commitLol.getCommitID(), null, "2024-01-08 10:00", new HashMap<>(), new ArrayList<>());
        commitHow.saveCommit();
        Commit commitFar = new Commit("Commit far", commitHow.getCommitID(), null, "2024-01-09 10:00", new HashMap<>(), new ArrayList<>());
        commitFar.saveCommit();
        // 输出提交树
        System.out.println("Commit tree created with structure similar to the provided image.");


        Set<String> expectedAncestorIDs = new HashSet<>(Arrays.asList(init.getCommitID(), commitA.getCommitID(), commitC.getCommitID(),
                commitE.getCommitID(), commitF.getCommitID(), commitG.getCommitID()));
        Assert.assertEquals(expectedAncestorIDs, MergeUtils.findAllCommitAncestors(commitG.getCommitID()));
        Set<String> answer = MergeUtils.findAllCA(commitD.getCommitID(),commitG.getCommitID());
        Set<String> expected = new HashSet<>();
        expected.add(commitA.getCommitID());
        expected.add(init.getCommitID());
        Assert.assertEquals(expected,answer);



        Set<String> lca = new HashSet<>();
        lca.add(commitA.getCommitID());
        Assert.assertEquals(lca,MergeUtils.findLCA(commitD.getCommitID(),commitG.getCommitID()));
        Assert.assertEquals(expected,answer);

    }

    @Test
    public void findTwoLCATest() {
        Commit grandpa = new Commit("Initial commit", null, null, "2024-01-01 10:00", new HashMap<>(), new ArrayList<>());
        grandpa.saveCommit();
        Commit father = new Commit("Vincnettttt piggy commit", grandpa.getCommitID(), null, "2024-01-01 10:00", new HashMap<>(), new ArrayList<>());
        father.saveCommit();
        Commit mother = new Commit("Mother's commit", grandpa.getCommitID(), null, "2024-01-01 10:00", new HashMap<>(), new ArrayList<>());
        mother.saveCommit();
        Commit son1 = new Commit("Vincent Idoit commit", father.getCommitID(), mother.getCommitID(), "2024-01-01 10:00", new HashMap<>(), new ArrayList<>());
        son1.saveCommit();
        Commit son2 = new Commit("Bad Vincent commit", father.getCommitID(), mother.getCommitID(), "2024-01-01 10:00", new HashMap<>(), new ArrayList<>());
        son2.saveCommit();
        Commit son3 = new Commit("Chou Vincent commit", father.getCommitID(), mother.getCommitID(),"2024-01-01 10:00", new HashMap<>(), new ArrayList<>());
        son3.saveCommit();


        Set<String> lca = new HashSet<>();
        lca.add(mother.getCommitID());
        lca.add(father.getCommitID());

        Set<String> lca1 = new HashSet<>();
        lca1.add(son3.getCommitID());

        Set<String> lca2 = new HashSet<>();
        lca2.add(mother.getCommitID());

        Assert.assertEquals(lca,MergeUtils.findLCA(son3.getCommitID(),son2.getCommitID()));
        Assert.assertEquals(lca1,MergeUtils.findLCA(son3.getCommitID(),son3.getCommitID()));
        Assert.assertEquals(lca2,MergeUtils.findLCA(son3.getCommitID(),mother.getCommitID()));






    }


    @Test
    public void findLCATest(){

        Commit grandpa = new Commit("Initial commit", null, null, "2024-01-01 10:00", new HashMap<>(), new ArrayList<>());
        grandpa.saveCommit();
        Commit c1 = new Commit("commit 1", grandpa.getCommitID(), null, "2024-01-01 10:00", new HashMap<>(), new ArrayList<>());
        c1.saveCommit();
        Commit c2 = new Commit("commit 2", c1.getCommitID(), null, "2024-01-01 10:00", new HashMap<>(), new ArrayList<>());
        c2.saveCommit();
        Commit c3 = new Commit("commit 3", c1.getCommitID(), null, "2024-01-01 10:00", new HashMap<>(), new ArrayList<>());
        c3.saveCommit();


        Assert.assertEquals(grandpa.getCommitID(),MergeUtils.findLCA(c2.getCommitID(),c3.getCommitID()));


    }
}



